package com.financing.wap.web.controller.api;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.financing.wap.util.*;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.financing.wap.common.ResultMap;
import com.financing.wap.common.ResultMap.STATUS;
import com.financing.wap.common.Session;
import com.financing.wap.common.SessionUtil;
import com.financing.wap.dto.UserDTO;
import com.financing.wap.service.ISmsNewService;
import com.financing.wap.service.ISmsService;
import com.financing.wap.service.IUserService;
import com.financing.wap.web.controller.BaseController;

/**
 * 发送OTPcontroller
 * @author hetaihe
 *
 */
@Controller("apiSendOtpController")
@RequestMapping("/api/otp")
public class SendOtpController extends BaseController {

	/**
	 * 工具类
	 */
	@Autowired
	public ISmsService smsService;
	
	@Autowired
	public ISmsNewService smsNewService;

	@Autowired
	private IUserService userService;
	

	@RequestMapping(value="/sendRegVcode")
	@ResponseBody
	public ResultMap sendRegVcode(String mobile,HttpServletRequest request){
		ResultMap returnResult = new ResultMap();
		String verifyCode = (String)SessionUtil.getSession().getAttribute(Constants.SESSION_KEY_VERIFYCODE);
		String requestVerifyCode = request.getParameter("verifyCode");
		log.info("verifyCode is :"+verifyCode);
		log.info("requestVerifyCode is :"+requestVerifyCode);
		if(StringUtils.isEmpty(verifyCode)||!verifyCode.equals(requestVerifyCode.toLowerCase())){
			returnResult.setStatus(STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.LOGIN_VERIFYCODE_ERROR);
			returnResult.setMessage("图片验证码错误");
			return returnResult;
		}
		request.setAttribute("ct", request.getParameter("ct"));
		return sendVcode(mobile,request,true,Constants.regSmsAd);
		
	}
	
	/**
	 * 
	
	* @Title: sendLoginVcode
	
	* @Description: 登录验证码
	
	* @param @param mobile
	* @param @param request
	* @param @return    设定文件
	
	* @return ResultMap    返回类型
	
	* @throws
	 */
	@RequestMapping(value="/sendLoginVcode")
	@ResponseBody
	public ResultMap sendLoginVcode(String mobile,HttpServletRequest request){
		ResultMap returnResult = new ResultMap();
		String verifyCode = (String)SessionUtil.getSession().getAttribute(Constants.SESSION_KEY_VERIFYCODE);
		String requestVerifyCode = request.getParameter("verifyCode");
		log.info("verifyCode is :"+verifyCode);
		log.info("requestVerifyCode is :"+requestVerifyCode);
		Map<String, Object> parameterMap = getParameterMap(request);
		if(parameterMap.containsKey("verifyCode")){
			if(StringUtils.isEmpty(verifyCode)||!verifyCode.equals(requestVerifyCode.toLowerCase())){
				returnResult.setStatus(STATUS.FAILE);
				returnResult.setStatusCode(ResultMap.LOGIN_VERIFYCODE_ERROR);
				returnResult.setMessage("图片验证码错误");
				return returnResult;
			}
		}
		request.setAttribute("ct", "login");
		return sendVcode(mobile,request,true,Constants.loginSmsAdShop);
		
	}
	/**
	 * 
	
	* @Title: sendLoginVcode
	
	* @Description: 登录验证码
	
	* @param @param mobile
	* @param @param request
	* @param @return    设定文件
	
	* @return ResultMap    返回类型
	
	* @throws
	 */
	@RequestMapping(value="/sendLoginVcode2")
	@ResponseBody
	public ResultMap sendLoginVcode2(String mobile,HttpServletRequest request){
		ResultMap returnResult = new ResultMap();
		String verifyCode = (String)SessionUtil.getSession().getAttribute(Constants.SESSION_KEY_VERIFYCODE);
		String requestVerifyCode = request.getParameter("verifyCode");
		log.info("verifyCode is :"+verifyCode);
		log.info("requestVerifyCode is :"+requestVerifyCode);
//		Map<String, Object> parameterMap = getParameterMap(request);
//		if(parameterMap.containsKey("verifyCode")){
			if(StringUtils.isEmpty(verifyCode)||!verifyCode.equals(requestVerifyCode.toLowerCase())){
				returnResult.setStatus(STATUS.FAILE);
				returnResult.setStatusCode(ResultMap.LOGIN_VERIFYCODE_ERROR);
				returnResult.setMessage("图片验证码错误");
				return returnResult;
			}
//		}
		request.setAttribute("ct", "login");
		return sendVcode(mobile,request,true,Constants.loginSmsAdShop);
		
	}
	//预约分享短信
	@RequestMapping(value="/shareMakeVcode")
	@ResponseBody
	public ResultMap shareMakeVcode(String mobile,HttpServletRequest request){
		request.setAttribute("ct", "shareMake");
		return sendVcode(mobile,request,true,Constants.shareMakeSendSms);
		
	}
	
	
	private ResultMap sendVcode(String mobile,HttpServletRequest request,boolean isNewSms,String smsType){
		ResultMap returnResult = new ResultMap();
		
		try{
			if(StringUtils.isBlank(mobile)){
				log.info("mobile is null");
				returnResult.setStatus(ResultMap.STATUS.FAILE);
				returnResult.setStatusCode(ResultMap.STATUS_CODE_OTP_VALIDATE_ERROR_NULL);
				returnResult.setMessage("手机号码为空！");
				return returnResult;
			}
			log.info("check opt!");
			
			//每个手机号1小时最多10条短信
			Integer i  = (Integer)MemcacheCacheHelper.mcc.get(mobile);
			Date time = (Date) MemcacheCacheHelper.mcc.get(mobile+"Time");
			Date now = new Date();
			Integer optFrequency = 5;
			Long optTimeOut = 7200000L;
			
			log.info(i+","+time+","+optTimeOut+","+now+","+optFrequency);
					
			if(i == null || optFrequency == null){
				i=1;
				MemcacheCacheHelper.mcc.set(mobile,i);
				MemcacheCacheHelper.mcc.set(mobile+"Time", new Date());
			}else if(i < optFrequency){
				i++;
				MemcacheCacheHelper.mcc.set(mobile,i);
			}else if(i >= optFrequency && (now.getTime() - time.getTime() > optTimeOut)){
				MemcacheCacheHelper.mcc.set(mobile,1);
				MemcacheCacheHelper.mcc.set(mobile+"Time", new Date());
			}else{
				returnResult.setStatus(ResultMap.STATUS.FAILE);
				returnResult.setStatusCode(ResultMap.STATUS_CODE_OTP_BUSY_ERROR);
				returnResult.setMessage("验证码获取太频繁，请稍后重试！");
				return returnResult;
			}

			String ip = IPUtil.getRemoteHost(request);
			//每个ip1小时最多100条短信
			Integer ip_i  = (Integer)MemcacheCacheHelper.mcc.get(ip);
			Date ip_time = (Date) MemcacheCacheHelper.mcc.get(ip+"Time");
			Integer ip_optFrequency = 80;
			Long ip_optTimeOut = 7200000L;

			log.info(ip_i+","+ip_time+","+ip_optTimeOut+","+now+","+ip_optFrequency);

			if(ip_i == null || ip_optFrequency == null){
				ip_i=1;
				MemcacheCacheHelper.mcc.set(ip,ip_i);
				MemcacheCacheHelper.mcc.set(ip+"Time", new Date());
			}else if(ip_i < ip_optFrequency){
				ip_i++;
				MemcacheCacheHelper.mcc.set(ip,ip_i);
			}else if(ip_i >= ip_optFrequency && (now.getTime() - ip_time.getTime() > ip_optTimeOut)){
				MemcacheCacheHelper.mcc.set(ip,1);
				MemcacheCacheHelper.mcc.set(ip+"Time", new Date());
			}else{
				returnResult.setStatus(ResultMap.STATUS.FAILE);
				returnResult.setStatusCode(ResultMap.STATUS_CODE_OTP_BUSY_ERROR);
				returnResult.setMessage("验证码获取太频繁，请稍后重试！");
				return returnResult;
			}



			/** check tag 用来进行校验的标识 */
			String ct = "";
			try {
				ct = (String) request.getAttribute("ct");
			} catch (Exception e) {
				ct = null;
			}
			
			if(StringUtils.isBlank(ct)){//如果没有标识 则进行手机号重名认证
				if(userService.isMobileRegistered(mobile)){
					log.info("repeat mobile no");
					//已经被注册
					returnResult.setStatus(ResultMap.STATUS.FAILE);
					returnResult.setStatusCode(ResultMap.STATUS_CODE_MOBILE_NUMBER_CONFLICT);
					returnResult.setMessage("手机号码已经被注册！");
					return returnResult;
				}
			}
			
			Integer activety_otp_time= new Integer(PropertiesUtils.getValue("activety_otp_time"));
			
			ResultMap smsResult = null;
			log.info("==otp time out ==  1");
			String sendType="regVcode";
			if("login".equals(ct)){
				sendType="vCodeDefault";
				
				String codeFlag = request.getParameter("codeFlag");//短信类型
				if(StringUtils.equals(codeFlag, "register")) {//注册
					sendType = "registerCode";
				} else if(StringUtils.equals(codeFlag, "forgetPasswd")) {//忘记密码
					sendType = "forgetPasswd";
				}
			}else if("shareMake".equals(ct)){
				sendType="shareMake";   //预约短信
			}
			
			
			
			
			Map<String,Object> param = new HashMap<String,Object>();
			if(checkOtpCodeTimeOut(mobile,activety_otp_time,ISmsService.OTP_CODE_FIRST_TIME)){
				param.put("vCode", RandomUtils.getRandomUtils(6));
				String msg = (String) MessageUtil.getMessage("messageAndMail", sendType, param).get(MessageUtil.KEY_CONTENT);
				//发送手机号码
				if(isNewSms){
					smsResult = smsNewService.sendOtpMessage(mobile,msg,smsType);
				}else{
					smsResult = smsService.sendOtpMessage(mobile, msg, smsType);
				}
				smsResult.setAttribute(ISmsService.OTP_CODE, param.get("vCode"));
				super.getSession(true).setAttribute(ISmsService.OTP_CODE_FIRST_TIME+mobile, new Date());
				log.info("==otp time out ,send end ==");
			}else{
				log.info("==otp from session ==");
				String tempCode = (String)super.getSession(true).getAttribute(ISmsService.OTP_CODE+mobile);
				
				if(StringUtils.isBlank(tempCode)){
					tempCode = RandomUtils.getRandomUtils(6);
				}
				param.put("vCode", tempCode);
				String msg = (String) MessageUtil.getMessage("messageAndMail", sendType, param).get(MessageUtil.KEY_CONTENT);
				if(isNewSms){
					smsResult = smsNewService.sendOtpMessage(mobile,msg,smsType);
				}else{
					smsResult = smsNewService.sendOtpMessage(mobile,msg,smsType);
				}
				smsResult.setAttribute(ISmsService.OTP_CODE, tempCode);
				log.info("==otp from session ,send end ==");
			}
			//校验发送结果
			if(STATUS.SUCCESS.equals(smsResult.getStatus())){
				//发送成功
				String vCode = (String) smsResult.getAttribute(ISmsService.OTP_CODE);
				super.getSession(true).setAttribute(ISmsService.OTP_CODE+mobile, vCode);
				super.getSession(true).setAttribute(ISmsService.OTP_CODE_LAST_TIME+mobile, new Date());
				//返回处理结果
				returnResult.setStatus(STATUS.SUCCESS);
				returnResult.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
				returnResult.setMessage("发送成功!");
				SessionUtil.getSession().setAttribute(Constants.SESSION_KEY_VERIFYCODE,null);
				returnResult.setAttribute("statusCode", ResultMap.STATUS_CODE_SUCCESS);
				return returnResult;
			}else{
	
				//发送失败
				returnResult.setStatus(STATUS.FAILE);
				returnResult.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);
				returnResult.setMessage(smsResult.getMessage());
	
				return returnResult;
			}
		}catch(Exception e){
			log.error("send otp error!",e);
			//发送失败
			returnResult.setStatus(STATUS.ERROR);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_SYS_EXCEPTION);

			return returnResult;
		}
	}
	

	
	/**忘记密码 - 发送短信验证码
	 *  判断手机号是否存在  不存在 return error 
	 *  与上方法相反
	 * @param mobile
	 * @return
	 */
	@RequestMapping(value="/sendVcodeForget")
	@ResponseBody
	public ResultMap sendVcodeForgetPassWord(String mobile,HttpServletRequest request){
		log.info("In sendVcodeForgetPassWord Begin!");
		
		ResultMap returnResult = new ResultMap();
		
		String verifyCode = (String)SessionUtil.getSession().getAttribute(Constants.SESSION_KEY_VERIFYCODE);
		String requestVerifyCode = request.getParameter("verifyCode");
		log.info("verifyCode is :"+verifyCode);
		log.info("requestVerifyCode is :"+requestVerifyCode);
		if(StringUtils.isEmpty(verifyCode)||!verifyCode.equals(requestVerifyCode.toLowerCase())){
			returnResult.setStatus(STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.LOGIN_VERIFYCODE_ERROR);
			returnResult.setMessage("图片验证码错误");
			return returnResult;
		}
		
		if(StringUtils.isBlank(mobile)){
			log.info("mobile is null");
			returnResult.setStatus(ResultMap.STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_OTP_VALIDATE_ERROR_NULL);
			returnResult.setMessage("手机号码为空！");
			return returnResult;
		}
		if(!userService.isMobileRegistered(mobile)){
			log.info("repeat mobile undefined");
			//手机号在本系统中不存在 不能重置密码
			returnResult.setStatus(ResultMap.STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_MOBILE_NUMBER_UNDEFINED);
			returnResult.setMessage("手机号在本系统中不存在！");
			return returnResult;
		}
		
		
		return sendMessage(mobile, returnResult,Constants.passwdRsetSmsAd,"forgetPasswd");
	}
	/**
	 *  
	 * 登陆后发生验证码-手机号取登录名
	 * @return
	 */
	@RequestMapping(value="/sendMessageCode")
	@ResponseBody
	public ResultMap sendMessageCode(HttpServletRequest request){
		log.info("In sendVcodeForgetPassWord Begin!");
		ResultMap returnResult = new ResultMap();
		Session session = SessionUtil.getSession();
		
		String verifyCode = (String)SessionUtil.getSession().getAttribute(Constants.SESSION_KEY_VERIFYCODE);
		String requestVerifyCode = request.getParameter("verifyCode");
		log.info("verifyCode is :"+verifyCode);
		log.info("requestVerifyCode is :"+requestVerifyCode);
		if(StringUtils.isEmpty(verifyCode)||!verifyCode.equals(requestVerifyCode.toLowerCase())){
			returnResult.setStatus(STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.LOGIN_VERIFYCODE_ERROR);
			returnResult.setMessage("图片验证码错误");
			return returnResult;
		}
		
		String mobile="";
		
		if(session == null || session.getLogin() == false || session.getUser()==null){
			returnResult.setStatus(STATUS.NEED_LOGIN);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_ONLOGIN);
			returnResult.setMessage("Need login");
			returnResult.setAttribute(Constants.ResultMessage,"未登录,请先登录");
			return returnResult;
		}
		
		//获取登录名

		UserDTO loginUser = session.getUser();
		mobile = loginUser.getLoginName();
			
		if(StringUtils.isBlank(mobile)){
			log.info("mobile is null");
			returnResult.setStatus(ResultMap.STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_OTP_VALIDATE_ERROR_NULL);
			returnResult.setMessage("手机号码为空！");
			return returnResult;
		}
		if(!userService.isMobileRegistered(mobile)){
			log.info("repeat mobile undefined");
			//手机号在本系统中不存在 不能重置密码
			returnResult.setStatus(ResultMap.STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_MOBILE_NUMBER_UNDEFINED);
			returnResult.setMessage("手机号在本系统中不存在！");
			return returnResult;
		}
		
		String smsType = request.getParameter("smsType");
		
		String smsTemplate = null;
		if("changePwd".equals(smsType)){
			smsTemplate = "changePwd";
			smsType = Constants.changePwdSmsAd;
		}else if("bindBankCard".equals(smsType)){
			smsTemplate = "bindBankCard";
			smsType = Constants.bindBankCardSmsAd;
		}else{
			smsTemplate = "vCodeDefault";
			smsType = Constants.changePwdSmsAd;
		}
		
		return sendMessage(mobile, returnResult,smsType,smsTemplate);
	}
	private ResultMap sendMessage(String mobile, ResultMap returnResult,String smsType,String smsTemplate) {
		ResultMap smsResult = null;
		
		//每个手机号1小时最多10条短信
		Integer i  = (Integer)MemcacheCacheHelper.mcc.get(mobile);
		Date time = (Date) MemcacheCacheHelper.mcc.get(mobile+"Time");
		Date now = new Date();
		Integer optFrequency = 5;
		Long optTimeOut = 7200000L;
		
		log.info(i+","+time+","+optTimeOut+","+now+","+optFrequency);
		
		if(i == null || optFrequency == null){
			i=1;
			MemcacheCacheHelper.mcc.set(mobile,i);
			MemcacheCacheHelper.mcc.set(mobile+"Time", new Date());
		}else if(i < optFrequency){
			i++;
			MemcacheCacheHelper.mcc.set(mobile,i);
		}else if(i >= optFrequency && (now.getTime() - time.getTime() > optTimeOut)){
			MemcacheCacheHelper.mcc.set(mobile,1);
			MemcacheCacheHelper.mcc.set(mobile+"Time", new Date());
		}else{
			returnResult.setStatus(ResultMap.STATUS.FAILE);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_OTP_BUSY_ERROR);
			returnResult.setMessage("验证码获取太频繁，请稍后重试！");
			return returnResult;
		}

		
		Integer activety_otp_time= new Integer(PropertiesUtils.getValue("activety_otp_time"));
		
		Map<String,Object> param = new HashMap<String,Object>();
		
		//判断时间是否超过 activety_otp_time，超时重新生成验证码，不超时复用原来的验证码
		if(checkOtpCodeTimeOut(mobile,activety_otp_time,ISmsService.OTP_CODE_FIRST_TIME)){
			log.info("==otp time out ==");
			//发送手机号码
			param.put("vCode", RandomUtils.getRandomUtils(6));
			
			String message = (String) MessageUtil.getMessage("messageAndMail", smsTemplate, param).get(MessageUtil.KEY_CONTENT);
			smsResult = smsService.sendOtpMessage(mobile,message,smsType);
			smsResult.setAttribute(ISmsService.OTP_CODE, param.get("vCode"));
			super.getSession(true).setAttribute(ISmsService.OTP_CODE_FIRST_TIME+mobile, new Date());
			log.info("==otp time out ,send end ==");
		}else{
			log.info("==otp from session ==");
			String tempCode = (String)super.getSession(true).getAttribute(ISmsService.OTP_CODE+mobile);
			param.put("vCode", tempCode);
			String message = (String) MessageUtil.getMessage("messageAndMail", smsTemplate, param).get(MessageUtil.KEY_CONTENT);
			smsResult = smsService.sendOtpMessage(mobile,message,smsType);
			smsResult.setAttribute(ISmsService.OTP_CODE, tempCode);
			log.info("==otp from session ,send end ==");
		}
		//校验发送结果
		if(STATUS.SUCCESS.equals(smsResult.getStatus())){
			//发送成功
			String vCode = (String) smsResult.getAttribute(ISmsService.OTP_CODE);
			super.getSession(true).setAttribute(ISmsService.OTP_CODE+mobile, vCode);
			super.getSession(true).setAttribute(ISmsService.OTP_CODE_LAST_TIME+mobile, new Date());
			//返回处理结果
			returnResult.setStatus(STATUS.SUCCESS);
			returnResult.setStatusCode(ResultMap.STATUS_CODE_SUCCESS);
			returnResult.setMessage("发送成功!");
			return returnResult;
		}else{

			//发送失败
			returnResult.setStatus(STATUS.FAILE);
			returnResult.setMessage(smsResult.getMessage());

			return returnResult;
		}
	}
	
	public ResultMap sendMessageCodeByCardBinding(String mobile){
		ResultMap returnResult = new ResultMap();
		String smsType = Constants.bindBankCardSmsAd;
		String smsTemplate = "bindBankCard";
		return sendMessage(mobile, returnResult,smsType,smsTemplate);
	}
	
	public static void main(String[] args) {
		String a = "2017-03-23 16:00:00";
		String b = "2017-03-23 18:00:00";
		long aa = DateUtil.format(a, null).getTime();
		long bb = DateUtil.format(b, null).getTime();
		
		System.out.println(bb-aa);
	}
}